package CCRMClient;
 
import ocsf.client.*;
import Common.*;
import Common.Entities.*;
import CCRMClient.Controllers.*;
import CCRMClient.GUI.AddCustomerScreen;
import CCRMClient.GUI.AddTypeScreen;
import CCRMClient.GUI.CatalogScreen;
import CCRMClient.GUI.ChooseTaskForce;
import CCRMClient.GUI.CustomerManage;
import CCRMClient.GUI.CustomerResponseScreen;
import CCRMClient.GUI.CustomersReportScreen;
import CCRMClient.GUI.EmployeePortal;
import CCRMClient.GUI.MarketingManagementScreen;
import CCRMClient.GUI.MarketingScreen;
import CCRMClient.GUI.ProductSearchScreen;
import CCRMClient.GUI.SaleDetailsScreen;
import CCRMClient.GUI.SaleInitiationScreen;
import CCRMClient.GUI.SalesReportScreen;
import CCRMClient.GUI.SalesScreen;
import CCRMClient.GUI.SearchCustomerScreen;
import CCRMClient.GUI.TemplateAssignCustomersScreen;
import CCRMClient.GUI.TemplateChangeStatusScreen;
import CCRMClient.GUI.TemplateManagementScreen;
import CCRMClient.GUI.TemplateMarketingManagerScreen;
import CCRMClient.GUI.TemplateSearchScreen;
import CCRMClient.GUI.TemplateAddScreen;
import CCRMClient.GUI.TemplateUpdateScreen;
import CCRMClient.GUI.CustomersForSaleScreen;




import CCRMClient.GUI.UpdateProductScreen;
import CCRMClient.GUI.ViewProductScreen;

import java.io.*;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JPanel;




/**
 * This class overriding an Abstract client class
 * @author Ola
 *
 */

public class CCRMClient extends AbstractClient {
		
	public CCRMClient(String host, int port) throws IOException {
		    super(host, port); //Call the superclass constructor
		    openConnection();
		  }
	 /**
	   * This method handles all data that comes in from the server and send it to GUI to show us results.
	   *
	   * @param msg The message is answer from the server.
	   */
	
	/* (non-Javadoc)
	 * @see ocsf.client.AbstractClient#handleMessageFromServer(java.lang.Object)
	 */
	public void handleMessageFromServer(Object msg) {
		ServerAnswer answer = (ServerAnswer)msg;
		
		switch (answer.getCommand()) {
		case LOG_IN:
			if (answer.getMessage().equals("Welcome to CCRM!")) {
				ClientStart.user = (Employee)answer.getAnswer(); 
				ClientStart.panelSwicher(new EmployeePortal());
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Welcome", "INFORMATION_MESSAGE");
			} else {
				ClientStart.appWindow.handleResponseFromClient(answer.getMessage());
			}
			break;
		case LOG_OUT:
			try {
				ClientStart.client.closeConnection();
				ClientStart.user = null;
				JPanel login = ClientStart.appWindow.getLogin();
				login.setSize(380, 365);
				ClientStart.panelSwicher(login);
			} catch (IOException e) {
				quit();
			}
			break;
			/**
			 * GET_CUSTOMER_BY_CONDITION:
			 * this case receive answer with array list of found customers.
			 * @author Ola
			 */
		case GET_CUSTOMER_BY_CONDITION:
			if (answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("DB Problem", "Search Product", "ERROR_MESSAGE");
			else 
				ClientStart.panelSwicher(new SearchCustomerScreen((ResultSet)answer.getAnswer(), answer.getMessage()));
				
			
			break;
			/**
			 * ADD_CUSTOMER:
			 * this case receive answer from the server if customer added DB or not.
			 * @author Ola
			 * 
			 */
		case ADD_CUSTOMER:
			if(answer.getMessage().equals("Customer already exists"))
				ClientStart.appWindow.notifyUser("Customer already exist ", answer.getMessage(), "ERROR_MESSAGE");
			else if(answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
			else if(answer.getMessage().equals("Region not exists"))
				ClientStart.appWindow.notifyUser("Region not exist", answer.getMessage(), "ERROR_MESSAGE");
			else {
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Customer", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new CustomerManage());
			}
			break;
			/**
			 * UPDATE_CUSTOMER:
			 * this case receive answer from the server if customer  are updated in the DB of not.
			 * @author Ola
			 */
		case UPDATE_CUSTOMER:
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Update Customer", "INFORMATION_MESSAGE");
			if (answer.getMessage().equals("Update succeeded"))
				ClientStart.panelSwicher(new CustomerManage());
			break;
			/**
			 * UPDATE_CUSTOMER_STATUS:
			 * this case receive answer from the server if customer status are changs in the DB.
			 */
		case UPDATE_CUSTOMER_STATUS:
			if(answer.getMessage().equals("Customer not exists"))
				ClientStart.appWindow.notifyUser("Customer not exist ", answer.getMessage(), "ERROR_MESSAGE");
			else
				if(answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Update Customer", "INFORMATION_MESSAGE");
			///
			break;
			/**
			 * ADD_PERMISSION:
			 * this case receive answer from the server that permission was added to the DB.
			 */
		case ADD_PERMISSION:
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Permission", "INFORMATION_MESSAGE");
			ClientStart.panelSwicher(new CustomerManage());
			break;
			/**
			 * GET_REGIONS
			 * this case receive answer from the server with array list of regions from the DB.
			 */
		case GET_REGIONS:
	
			  break;
			  /**
			   * ADD_REGION:
			   * this case receive answer from the server if new region was added or not.
			   */
		 case ADD_REGION:
			 if(answer.getMessage().equals("Region already exists"))
				 ClientStart.appWindow.notifyUser("Region already exists ", answer.getMessage(), "ERROR_MESSAGE");
			 else if(answer.getMessage().equals("DB Problem"))
				 ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
			 ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Region", "INFORMATION_MESSAGE");
			  break; 
		case ADD_CATEGORY:
			if (answer.getAnswer() == null)
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Category", "INFORMATION_MESSAGE");
			else
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Category", "INFORMATION_MESSAGE");
			ClientStart.panelSwicher(new CatalogScreen());
			break;
		case ADD_SALE:
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Sale", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new MarketingManagementScreen());
			break;
		case GET_CATEGORY_TYPES:
			if (answer.getAnswer() == null)
				if (answer.getMessage().equals("DB Problem"))
					ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
				else if (answer.getMessage().equals("Category does not exsits"))
					ClientStart.appWindow.notifyUser(answer.getMessage(), "Category Types", "INFORMATION_MESSAGE");
				else
					ClientStart.appWindow.notifyUser(answer.getMessage(), "Category Types", "ERROR_MESSAGE");
			else
				ClientStart.panelSwicher(new AddTypeScreen((ResultSet)answer.getAnswer(), answer.getMessage()));
			break;
		case ADD_TYPE:
			if (answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
			else
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Type", "INFORMATION_MESSAGE");
			break;
		default:
			break;
		case ADD_TEMPLATE:
			String message = answer.getMessage();
			switch (message) {
			case "Action succeeded":
				ClientStart.appWindow.notifyUser("Template successfully added", "Action succeeded", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateManagementScreen());
				break;
			case "DB Problem":
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
				break;
			case "Product not exists in DB":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
			case "Product status is not active":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
			case "Product already related to another template":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
				break;
			case "Template already exists":
				ClientStart.appWindow.notifyUser("Template already exist", "Action Failed", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
				break;
			case "All fields are mandatory":
				ClientStart.appWindow.notifyUser("All fields are mandatory", "Action Failed", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new TemplateAddScreen());
				break;
			}
			break;
		case SEARCH_TEMPLATE:
			message = answer.getMessage();
			switch (message) {
			case "Action succeded":
				ClientStart.panelSwicher(new TemplateSearchScreen((MarketingTemplate)answer.getAnswer()));
				ClientStart.appWindow.setSize(450,371);
				break;
			case "DB Problem":
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
				break;
			case "Template not exists":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				break;
			}
			break;
		case ADD_PRODUCT:
			message = answer.getMessage();
			switch (message) {
			case "Action succeeded":
			case "Action failed":
				ClientStart.appWindow.notifyUser(message, "Add Product", "INFORMATION_MESSAGE");
				break;
			case "DB Problem":
				ClientStart.appWindow.notifyUser(message, "Add Product", "ERROR_MESSAGE");
				break;
			default:
				ClientStart.appWindow.notifyUser(message, "Add Product", "ERROR_MESSAGE");
			}
			ClientStart.panelSwicher(new CatalogScreen());
			break;
		case SEARCH_PRODUCT:
			if (answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("DB Problem", "Search Product", "ERROR_MESSAGE");
			else
				ClientStart.panelSwicher(new ProductSearchScreen((ResultSet)answer.getAnswer(), answer.getMessage()));
			break;
		case VIEW_TEMPLATE:
			message = answer.getMessage();
			switch (message) {
			case "Action succeded":
				ClientStart.panelSwicher(new TemplateUpdateScreen((MarketingTemplate)answer.getAnswer()));
				ClientStart.appWindow.setSize(450,371);
				break;
			case "DB Problem":
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
				break;
			case "Template not exists":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				break;
			}
			break;
		case UPDATE_TEMPLATE:
			message = answer.getMessage();
			switch (message) {
			case "Action succeeded":
				ClientStart.appWindow.notifyUser("Template successfully updated", "Action succeeded", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateMarketingManagerScreen());
				break;
			case "DB Problem":
				ClientStart.appWindow.notifyUser("Could not connect to DB", answer.getMessage(), "ERROR_MESSAGE");
				ClientStart.panelSwicher(new TemplateUpdateScreen());
				break;
			case "Product not exists in DB":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateUpdateScreen());
			case "Product already related to another template":
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Action Failed", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new TemplateUpdateScreen());
				break;
			}
			break;
		case GET_PRODUCT:
			if (!answer.getMessage().isEmpty()) {
				ClientStart.appWindow.notifyUser(answer.getMessage(), "View Product", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new EmployeePortal());
			} else {
				File picFile = null;
				String picTitle = null;
				Product product = (Product)answer.getAnswer();
				if (product.getPicture() != null) {
					picFile = (CatalogManager.downloadPicture(product.getPicture()));
					picTitle = product.getPicture().getPictureTitle();
				}
				
				ClientStart.panelSwicher(new ViewProductScreen(product.getProductID(), product.getProductName(), product.getProductDescription(),
											product.getProductBasePrice(), product.getProductStatus(), product.getProductCategoriesAndTypes(), picTitle, picFile));
				
			}
			break;
		case GET_PRODUCT_UPDATE:
			if (!answer.getMessage().isEmpty()) {
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Update Product", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new UpdateProductScreen());
			} else {
				Object[] data = (Object[])answer.getAnswer();
				Product prd = (Product)data[0];
				File pic = CatalogManager.downloadPicture(prd.getPicture());
				ClientStart.panelSwicher(new UpdateProductScreen((Product)data[0], (LinkedList<Type>)data[1], pic));
			}
			break;

		case ASSIGN_TASKFORCE:
			Boolean success = (Boolean)answer.getAnswer();
			if(!success){
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Choose Task-Froce", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new MarketingScreen());
			}
			else{
				ClientStart.appWindow.notifyUser("Sale successfuly initieted!", "Sale initiaton", "INFORMATION_MESSAGE");
				ClientStart.panelSwicher(new MarketingScreen());
			}
			break;
		

		case UPDATE_PRODUCT_STATUS:
			if (!answer.getMessage().equals("DB Problem") && !answer.getMessage().equals("Product does not exists"))
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Status Update", "INFORMATION_MESSAGE");
			break;
		case UPDATE_PRODUCT:
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Product Update", "INFORMATION_MESSAGE");
			String statusChange = (String)answer.getAnswer();
			if (!statusChange.isEmpty())
				ClientStart.appWindow.notifyUser(statusChange, "Product Status Update", "INFORMATION_MESSAGE");
			break;
		case SEARCH_TEMPLATE_BY_STATUS:
			if (answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser("DB Problem", "Search Template", "ERROR_MESSAGE");
			else
				ClientStart.panelSwicher(new TemplateChangeStatusScreen((ResultSet)answer.getAnswer(), answer.getMessage()));
			break;
		case VIEW_SALES_FOR_SALESMAN :
			if(!answer.getMessage().isEmpty()) {
				ClientStart.appWindow.notifyUser(answer.getMessage(), "View my sales", "ERROR_MESSAGE");
				ClientStart.panelSwicher(new EmployeePortal());
			} else
				ClientStart.panelSwicher(new SalesScreen((ArrayList<String[]>) answer.getAnswer()));
			break;
		case CUSTOMERS_REPORT:
			if (answer.getMessage().isEmpty())
				ClientStart.panelSwicher(new CustomersReportScreen((ArrayList<String[]>)answer.getAnswer()));
			else
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Customers Report", "INFORMATION_MESSAGE");
			break;
		case SALES_REPORT:
			if (!answer.getMessage().isEmpty())
				ClientStart.panelSwicher(new SalesReportScreen((ArrayList<ResultSet>)answer.getAnswer()));
			else
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Sales Report", "INFORMATION_MESSAGE");
			
			break;
		case SEARCH_CUST_RATES:
			if (answer.getMessage().equals("DB Problem"))
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Search Customers Rates", "ERROR_MESSAGE");
			else
				ClientStart.panelSwicher(new TemplateAssignCustomersScreen((ArrayList<String[]>)answer.getAnswer(), answer.getMessage()));
			break;
		case ASSIGN_CUSTOMERS_TO_TEMPLATE:
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Assign Customers", "INFORMATION_MESSAGE");
			ClientStart.panelSwicher(new MarketingManagementScreen());
			break;
		case SHOW_CUSTOMERS_FOR_SALESMAN:
			if(!answer.getMessage().isEmpty())
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Sale Details", "INFORMATION_MESSAGE");
			else{
					ArrayList<String[]> customers = (ArrayList<String[]>)answer.getAnswer();
					ClientStart.panelSwicher(new CustomersForSaleScreen(customers));
			}
			break;
			
			
		case ADDRESS_CUSTOMER:
			if(!answer.getMessage().isEmpty())
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Address Customer", "INFORMATION_MESSAGE");
			else{
				String[] aData = (String[])answer.getAnswer();
				String saleID = aData[0];
				String customerID = aData[1];
				ClientStart.panelSwicher(new CustomerResponseScreen(saleID, customerID));
			}
			break;
		case ADD_RESPONSE:
			ClientStart.appWindow.notifyUser(answer.getMessage(), "Add Response", "INFORMATION_MESSAGE");
			break;
		case SHOW_SALE_DETAILS:
			if (answer.getMessage().isEmpty()) {
				ClientStart.panelSwicher(new SaleDetailsScreen((Sale) answer.getAnswer()));
			} else
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Display Sale", "INFORMATION_MESSAGE");
			break;
		case GET_APPROVED_TEMPLATES:
			if (!answer.getMessage().isEmpty())
				ClientStart.appWindow.notifyUser(answer.getMessage(), "Initiate Sale", "INFORMATION_MESSAGE");
			else
				ClientStart.panelSwicher(new SaleInitiationScreen((ResultSet) answer.getAnswer()));
			break;
	
			
		}
		
		
		
	}	

	

	
	/**
	 * this method handle message from GUI screen and send it to server with relevant parameters
	 * 
	 * @author Ola
	 * @param command-type of commands which user chose in GUI screen.
	 * @param data- this is parameters that was received from GUI screen.
	 * @throws IOException 
	 */
	
	public void handleMessageFromGUI (SERVER_COMMANDS command, Object data) throws IOException {
				
		switch (command) {
		
		case LOG_OUT:
			sendToServer(new ServerRequest(command, ClientStart.user.getUserName()));
			break;
			/**
			 * GET_CUSTOMER_BY_CONDITION:
			 * this case sends to the server request with customers parameters to search it from DB.
			 */
		case GET_CUSTOMER_BY_CONDITION:
			try {
				Employee emp = ClientStart.user;
				sendToServer(ClientCustomerManagement.SearchCustomerByCondition(command,(String)data));
			} catch (IOException e) {
				//ClientStart.appWindow.notifyUser(e1.getMessage(), "Sale Details", "ERROR_MESSAGE");
			}
			break;
		/**
		 * ADD_CUSTOMER:
		 * this case sends to the server request to add a new customer with all customer parameters.	
		 */
		case ADD_CUSTOMER:
			
			try {
				sendToServer(ClientCustomerManagement.addCustomer(command,(Customer)data));
			} catch (IOException e) {
				
				ClientStart.appWindow.notifyUser("Connection lost with the server", "Add Customer", "ERROR_MESSAGE");
				ClientStart.quitApp();
			}
			break;
			/**
			 * UPDATE_CUSTOMER:
			 * this case sends to the server request to update customer parameters.
			 */
		case UPDATE_CUSTOMER:
			
			try {
				sendToServer(ClientCustomerManagement.UpdateCustomer(command, (Customer)data));
			} catch (IOException e) {
				
				ClientStart.appWindow.notifyUser("Connection lost with the server", "Update Customer", "ERROR_MESSAGE");
				ClientStart.quitApp();
			}
			
			break;
			/**
			 * UPDATE_CUSTOMER_STATUS:
			 *  this case sends to the server request to update customer status in the DB.
			 *  
			 */
		case UPDATE_CUSTOMER_STATUS:
			
			sendToServer(ClientCustomerManagement.UpdateCustomerStatus(command,(String)data));
			break;
			/**
			 * GET_REGIONS
			 * this case sends to the server request to get region parameters from DB.
			 */
		case GET_REGIONS:
		sendToServer(ClientCustomerManagement.GetRegions(command));
			  break; 
			  /**
			   * ADD_REGION
			   * this case sends to the server request to add a new region to the DB.
			   */
		 case ADD_REGION:
			 sendToServer(ClientCustomerManagement.AddRegion(command,(Regions)data));
			  break;
	     case ADD_TEMPLATE:
	         sendToServer(data);
	 		 break;
	     case SEARCH_TEMPLATE:
	         sendToServer(data);
	 		 break;
	     case VIEW_TEMPLATE:
	         sendToServer(data);
	 		 break;
	     case UPDATE_TEMPLATE:
	         sendToServer(data);
	 		 break;
	     case ASSIGN_TASKFORCE:
	    	 sendToServer(ClientSaleManager.assigneToSale(command, (SalesTaskForce)data));
	    	 break;
	     case VIEW_SALES_FOR_SALESMAN:
	    	sendToServer(ClientSaleManager.showSalesForSalesman(command, (String)data));
	    	 break;
	     case SHOW_CUSTOMERS_FOR_SALESMAN:
	    	 sendToServer(ClientCustomerManagement.showCustomersForSalesmanInSale(command, (String[])data));
	    	 break;
	     case ADDRESS_CUSTOMER:
	    	 sendToServer(ClientCustomerManagement.checkCustomerAvailability(command, (String[])data));
	    	 break;
	     case ADD_RESPONSE:
	    	 sendToServer(ClientResponsesManagement.addResponse(command, (CustomerResponse)data));
	    	 break;
	     
	     

	     /*case SHOW_SALESMEN_AND_CUSTOMERS:
	    	 sendTServer(ClientCustomerManagement.getSalesManAndCustomers((Sale)data));
	    	 break;*/
	 	default:
	 		sendToServer(data);
	 		break;
		}
	}
	  public void quit() {
	    try
	    {
	      closeConnection();
	    }
	    catch(IOException e) {}
	    System.exit(0);
	  }
}

